package com.dtwenty.gaming.client;

import java.util.ArrayList;
import java.util.List;

import com.dtwenty.gaming.client.widgets.CharacterSheet;
import com.dtwenty.gaming.data.PlayerCharacter;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class CharacterManagementPanel extends Composite {
	private LoginInfo loginInfo = null;
	private List<String> usedNames = new ArrayList<String>();
	
	private DockPanel mainP = new DockPanel();
	private VerticalPanel mainPContent = new VerticalPanel();
	private Label info = new Label();
	private TextBox newPCName = new TextBox();
	private HorizontalPanel pcMenu = new HorizontalPanel();
	
	private PlayerCharacter selectedCharacter = null;
	
	public CharacterManagementPanel(LoginInfo loginInfo) {
		super();
		this.loginInfo = loginInfo;
		
		setup();
	}
	
	private void setup() {
		this.initWidget(mainP);
				
		pcMenu.add(new Button("Back", new ClickHandler() {
			public void onClick(ClickEvent ce) {
				mainP.clear();
				mainP.add(info, DockPanel.NORTH);
				mainP.add(mainPContent, DockPanel.CENTER);
			}
		}));
		
		pcMenu.add(new Button("Save", new ClickHandler() {
			public void onClick(ClickEvent ce) {
				savePC(selectedCharacter);
			}
		}));
		
//		mainP.add(new CharacterSheet(PlayerCharacter.createPlayerCharacter(DataType.CLIENT_SIDE)), DockPanel.CENTER);
		setupScreen1();
	}
	
	private void setupScreen1() {
		mainP.add(info, DockPanel.NORTH);
		mainP.add(mainPContent, DockPanel.CENTER);
		if(!loginInfo.isLoggedIn()) {
			info.setText("Please sign in to manage characters.");
		} else {
			info.setText("You are:" + loginInfo.getNickname());
			loadCharacters();
		}
	}
	
	private void setupScreen2() {
		mainP.add(pcMenu, DockPanel.NORTH);
		mainP.add(new CharacterSheet(selectedCharacter), DockPanel.CENTER);
	}
	private void loadCharacters() {
		DataBaseAsync db = GWT.create(DataBase.class);
		db.getCharacters(loginInfo, new AsyncCallback<List<PlayerCharacter>>() {
			public void onFailure(Throwable error) {
				info.setText(error.getMessage());
			}

			public void onSuccess(List<PlayerCharacter> result) {
				info.setText("You have " + result.size() + " characters.");
				
				usedNames.clear();
				mainPContent.clear();
				
				Button addNewPC = new Button("Add");
				addNewPC.addClickHandler(new ClickHandler() {
					public void onClick(ClickEvent ce) {
						createNewCharacter(newPCName.getText().trim());
					}
				});
				
				HorizontalPanel addP = new HorizontalPanel();
				addP.add(newPCName);
				addP.add(addNewPC);
				mainPContent.add(addP);
				
				for(PlayerCharacter pc : result) {
					usedNames.add(pc.getCharacterName());
					HorizontalPanel hp = new HorizontalPanel();
//					hp.add(new Button("delete"));
					Button b = new Button(pc.getCharacterName());
					b.addClickHandler(new LoadPlayerCharacterOnClick(pc));
					hp.add(b);
					mainPContent.add(hp);
				}
			}
		});
	}
	
	private void createNewCharacter(String name) {
		if(isCharacterNameUnique(name)) {
			PlayerCharacter newPC = new PlayerCharacter();
			newPC.setPlayerName(loginInfo.getEmailAddress());
			newPC.setCharacterName(name);
			savePC(newPC);
		} else {
			info.setText("The character " + name + " already exists.  Please choose another name.");
		}
	}

	private void savePC(PlayerCharacter pc) {
		if(isCharacterNameUnique(pc.getName())) {
			DataBaseAsync db = GWT.create(DataBase.class);
			db.saveData(pc, new AsyncCallback<String>() {
				public void onFailure(Throwable error) {
					info.setText("I'm sorry, but your character could not be created.  Please check with God and try again." + error);
				}

				public void onSuccess(String name) {
					info.setText(name + " has been successfully saved.");
					loadCharacters();
				}
			});
		}
	}

	private Boolean isCharacterNameUnique(String name) {
		for(String n : usedNames) if(name.equalsIgnoreCase(n)) return false;
		return true;
	}	
	
	private class LoadPlayerCharacterOnClick implements ClickHandler{
		private PlayerCharacter pc;
		
		public LoadPlayerCharacterOnClick(PlayerCharacter pc) {
			this.pc = pc;
		}
		
		public void onClick(ClickEvent ce) {
			selectedCharacter = pc;
			mainP.clear();
			setupScreen2();
		}
	}
}
